package com.cskaoyan.service;

import com.cskaoyan.bean.bo.*;
import com.cskaoyan.bean.po.*;
import com.cskaoyan.bean.vo.*;
import com.cskaoyan.mapper.*;
import com.cskaoyan.util.ConstantProperties;
import com.cskaoyan.util.Md5Util;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 系统管理
 * 管理员管理
 *
 * @author WuHuaguo
 * @since 2022/06/04 17:07
 */

@Service
public class SystemServiceImpl implements SystemService {

    @Autowired
    ConstantProperties CONSTANT;

    @Autowired
    AdminMapper adminMapper;

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    LogMapper logMapper;

    @Autowired
    PermissionMapper permissionMapper;

    @Autowired
    SystemPermissionsMapper systemPermissionsMapper;

    @Autowired
    PermissionUrlMapper permissionUrlMapper;

    /**
     * 获取管理员列表
     *
     * @param baseParam
     * @param username
     * @return com.cskaoyan.bean.vo.SystemAdminVO
     * @author WuHuaguo
     * @since 2022/06/05 11:26
     */
    @Override
    public SystemAdminVO adminList(BaseParam baseParam, String username) {
        // 分页
        PageHelper.startPage(baseParam.getPage(), baseParam.getLimit());

        AdminExample example = new AdminExample();
        // 查询结果按照addTime排序
        example.setOrderByClause(baseParam.getSort() + " " + baseParam.getOrder());

        AdminExample.Criteria criteria = example.createCriteria();
        if (username != null && !"".equals(username)) {
            // username非空
            criteria.andUsernameLike("%" + username + "%");
        }
        // 只展示逻辑未删除的管理员
        criteria.andDeletedEqualTo(false);

        // 查询
        List<Admin> admins = adminMapper.selectByExample(example);

        // 赋值
        ArrayList<AdminOfSystemAdminVO> adminList = new ArrayList<>();
        for (Admin admin : admins) {
            AdminOfSystemAdminVO adminVO = new AdminOfSystemAdminVO();
            adminVO.setId(admin.getId());
            adminVO.setAvatar(admin.getAvatar());
            adminVO.setUsername(admin.getUsername());
            adminVO.setRoleIds(admin.getRoleIds());
            adminList.add(adminVO);
        }

        // 获取分页后的结果
        PageInfo<AdminOfSystemAdminVO> pageInfo = new PageInfo<>(adminList);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();

        // 对systemAdminVO赋值
        SystemAdminVO systemAdminVO = new SystemAdminVO();
        systemAdminVO.setLimit(baseParam.getLimit());
        systemAdminVO.setPage(baseParam.getPage());
        systemAdminVO.setTotal((int) total);
        systemAdminVO.setPages(pages);
        systemAdminVO.setList(adminList);

        return systemAdminVO;
    }

    /**
     * 新增管理员
     *
     * @param createAdminBO
     * @return com.cskaoyan.bean.vo.SystemCreateAdminVO
     * @author WuHuaguo
     * @since 2022/06/06 20:42
     */
    @Override
    public SystemCreateAdminVO adminCreate(SystemCreateAdminBO createAdminBO) {
        AdminExample example = new AdminExample();
        AdminExample.Criteria criteria = example.createCriteria();
        criteria.andUsernameEqualTo(createAdminBO.getUsername());

        // 查询是否有存在相同管理员名字
        List<Admin> sameNameAdmin = adminMapper.selectByExample(example);
        if (sameNameAdmin != null && sameNameAdmin.size() != 0) {
            return null;
        }

        // 新增管理员
        Admin admin = new Admin();
        Date date = new Date();
        String password = Md5Util.getMD5(createAdminBO.getPassword());

        admin.setUsername(createAdminBO.getUsername());
        admin.setPassword(password);
        admin.setRoleIds(createAdminBO.getRoleIds());
        admin.setAvatar(createAdminBO.getAvatar());
        admin.setAddTime(date);
        admin.setUpdateTime(date);
        admin.setDeleted(false);

        // 新增管理员，并获取新增的管理员id
        int id = adminMapper.insert(admin);

        // 返回VO
        SystemCreateAdminVO createAdminVO = new SystemCreateAdminVO();
        createAdminVO.setId(id);
        createAdminVO.setPassword(password);
        createAdminVO.setAddTime(date);
        createAdminVO.setUpdateTime(date);
        createAdminVO.setUsername(createAdminBO.getUsername());
        createAdminVO.setRoleIds(createAdminBO.getRoleIds());
        createAdminVO.setAvatar(createAdminBO.getAvatar());
        return createAdminVO;
    }

    /**
     * 编辑管理员
     *
     * @param updateAdminBO
     * @return com.cskaoyan.bean.vo.SystemUpdateAdminVO
     * @author WuHuaguo
     * @since 2022/06/06 21:43
     */
    @Override
    public SystemUpdateAdminVO adminUpdate(SystemUpdateAdminBO updateAdminBO) {
        AdminExample example = new AdminExample();
        AdminExample.Criteria criteria = example.createCriteria();
        criteria.andUsernameEqualTo(updateAdminBO.getUsername());

        // 查询是否有存在其他相同名字的管理员
        List<Admin> sameNameAdmin = adminMapper.selectByExample(example);
        if (sameNameAdmin.size() == 1 && sameNameAdmin.get(0).getId() != updateAdminBO.getId()) {
            return null;
        }

        // 编辑管理员
        Admin admin = new Admin();
        Date date = new Date();
        String password = Md5Util.getMD5(updateAdminBO.getPassword());
        admin.setId(updateAdminBO.getId());
        admin.setPassword(password);
        admin.setUsername(updateAdminBO.getUsername());
        admin.setAvatar(updateAdminBO.getAvatar());
        admin.setRoleIds(updateAdminBO.getRoleIds());
        admin.setUpdateTime(date);

        // 编辑管理员操作
        adminMapper.updateByPrimaryKeySelective(admin);

        // 返回VO
        SystemUpdateAdminVO updateAdminVO = new SystemUpdateAdminVO();
        updateAdminVO.setId(updateAdminBO.getId());
        updateAdminVO.setAvatar(updateAdminBO.getAvatar());
        updateAdminVO.setRoleIds(updateAdminBO.getRoleIds());
        updateAdminVO.setUpdateTime(date);
        updateAdminVO.setUsername(updateAdminBO.getUsername());
        return updateAdminVO;
    }

    /**
     * 删除管理员
     *
     * @param deleteAdminBO
     * @return void
     * @author WuHuaguo
     * @since 2022/06/05 22:01
     */
    @Override
    public int adminDelete(SystemDeleteAdminBO deleteAdminBO) {
        Subject subject = SecurityUtils.getSubject();
        Admin adminNow = (Admin) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = adminNow.getId();

        if (userId == deleteAdminBO.getId()) {
            return CONSTANT.getFailCode1();
        }

        Admin admin = new Admin();
        admin.setId(deleteAdminBO.getId());
        admin.setDeleted(true);

        adminMapper.updateByPrimaryKeySelective(admin);
        return CONSTANT.getSuccessCode();
    }

    /**
     * 展示所有角色信息
     *
     * @return com.cskaoyan.bean.vo.SystemRoleOptionsVO
     * @author WuHuaguo
     * @since 2022/06/05 21:19
     */
    @Override
    public SystemRoleOptionsVO roleOptions() {
        RoleExample example = new RoleExample();
        List<Role> roles = roleMapper.selectByExample(example);

        ArrayList<RoleOfSystemRoleOptionsVO> roleList = new ArrayList<>();
        for (Role role : roles) {
            RoleOfSystemRoleOptionsVO optionVO = new RoleOfSystemRoleOptionsVO();
            optionVO.setValue(role.getId());
            optionVO.setLabel(role.getName());
            roleList.add(optionVO);
        }

        int total = roleList.size();

        SystemRoleOptionsVO systemRoleOptionsVO = new SystemRoleOptionsVO();
        systemRoleOptionsVO.setLimit(total);
        systemRoleOptionsVO.setTotal(total);
        systemRoleOptionsVO.setPage(CONSTANT.getPageDefault());
        systemRoleOptionsVO.setPages(CONSTANT.getPagesDefault());
        systemRoleOptionsVO.setList(roleList);

        return systemRoleOptionsVO;
    }

    /**
     * 获取角色列表
     *
     * @param baseParam
     * @param name
     * @return com.cskaoyan.bean.vo.SystemRoleVO
     * @author WuHuaguo
     * @since 2022/06/05 15:37
     */
    @Override
    public SystemRoleVO roleList(BaseParam baseParam, String name) {
        // 分页
        PageHelper.startPage(baseParam.getPage(), baseParam.getLimit());

        // 查询
        RoleExample example = new RoleExample();
        // 查询结果按照addTime排序
        example.setOrderByClause(baseParam.getSort() + " " + baseParam.getOrder());

        RoleExample.Criteria criteria = example.createCriteria();
        if (name != null && !"".equals(name)) {
            // username非空
            criteria.andNameLike("%" + name + "%");
        }

        // 只展示deleted为false的角色
        criteria.andDeletedEqualTo(false);

        List<Role> roles = roleMapper.selectByExample(example);

        // 赋值
        ArrayList<RoleOfSystemRoleVO> roleList = new ArrayList<>();
        for (Role role : roles) {
            RoleOfSystemRoleVO roleVO = new RoleOfSystemRoleVO();
            roleVO.setId(role.getId());
            roleVO.setName(role.getName());
            roleVO.setDesc(role.getDesc());
            roleVO.setDeleted(role.getDeleted());
            roleVO.setEnabled(role.getEnabled());
            roleVO.setAddTime(role.getAddTime());
            roleVO.setUpdateTime(role.getUpdateTime());
            roleList.add(roleVO);
        }

        // 获取分页后的结果
        PageInfo<RoleOfSystemRoleVO> pageInfo = new PageInfo<>(roleList);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();

        // 对systemRoleVO赋值
        SystemRoleVO systemRoleVO = new SystemRoleVO();
        systemRoleVO.setLimit(baseParam.getLimit());
        systemRoleVO.setPage(baseParam.getPage());
        systemRoleVO.setPages(pages);
        systemRoleVO.setTotal((int) total);
        systemRoleVO.setList(roleList);

        return systemRoleVO;
    }

    /**
     * 获取角色对应权限，以及系统全部权限
     *
     * @param roleId
     * @return com.cskaoyan.bean.vo.SystemPermissionsVO
     * @author WuHuaguo
     * @since 2022/06/07 10:44
     */
    @Override
    public SystemPermissionsVO rolePermissionsShow(Integer roleId) {
        SystemPermissionsVO permissionsVO = new SystemPermissionsVO();

        // 获取该角色已有的权限
        PermissionExample example = new PermissionExample();
        PermissionExample.Criteria criteria = example.createCriteria();
        criteria.andRoleIdEqualTo(roleId);
        criteria.andDeletedEqualTo(false);

        List<Permission> permissionList = permissionMapper.selectByExample(example);
        ArrayList<String> assignedPermissions = new ArrayList<>();

        for (Permission permission : permissionList) {
            assignedPermissions.add(permission.getPermission());
        }

        // 获取全部系统权限
        // 1. 查询一级权限（type = 1）
        List<SystemPermissionsVO.Child1> child1List =
                systemPermissionsMapper.queryLabelByType1(CONSTANT.getType1());

        // 2. 查询二级权限
        for (int i = 1; i < child1List.size() + 1; i++) {

            // 2.1 查询二级权限对应的id
            List<Integer> child2Id = systemPermissionsMapper.queryIdByPid(i);
            ArrayList<SystemPermissionsVO.Child1.Child2> child2List = new ArrayList<>();

            // 2.2 遍历二级权限对应的id数组
            for (Integer id : child2Id) {

                SystemPermissionsVO.Child1.Child2 child2 = systemPermissionsMapper.queryLabelById(id);

                // 3. 把二级权限id作为pid，查询三级权限，获取三级权限列表
                List<SystemPermissionsVO.Child1.Child2.Child3> child3List =
                        systemPermissionsMapper.queryLabelAndApiAndPermissionByPid(id);
                child2.setChildren(child3List);

                child2List.add(child2);
            }
            child1List.get(i - 1).setChildren(child2List);
        }

        permissionsVO.setAssignedPermissions(assignedPermissions);
        permissionsVO.setSystemPermissions(child1List);
        return permissionsVO;
    }

    /**
     * 新增角色的权限
     *
     * @param permissionsBO
     * @return void
     * @author WuHuaguo
     * @since 2022/06/07 14:46
     */
    @Override
    public void rolePermissionsAdd(SystemPermissionsBO permissionsBO) {
        // 先逻辑删除
        Integer roleId = permissionsBO.getRoleId();
        Permission oldPermission = new Permission();
        oldPermission.setDeleted(true);
        PermissionExample permissionExample = new PermissionExample();
        PermissionExample.Criteria criteria = permissionExample.createCriteria();
        criteria.andRoleIdEqualTo(roleId);
        permissionMapper.updateByExampleSelective(oldPermission, permissionExample);


        // 再新增
        Permission permission = new Permission();
        Date date = new Date();
        permission.setRoleId(roleId);
        permission.setAddTime(date);
        permission.setUpdateTime(date);
        permission.setDeleted(false);

        String[] permissions = permissionsBO.getPermissions();
        for (String s : permissions) {
            permission.setPermission(s);
            permissionMapper.insert(permission);
        }
    }

    /**
     * 新增角色
     *
     * @param createRoleBO
     * @return com.cskaoyan.bean.vo.RoleOfSystemRoleVO
     * @author WuHuaguo
     * @since 2022/06/05 16:33
     */
    @Override
    public RoleOfSystemRoleVO roleCreate(SystemCreateRoleBO createRoleBO) {
        // 新增
        Role role = new Role();
        Date date = new Date();
        role.setName(createRoleBO.getName());
        role.setDesc(createRoleBO.getDesc());
        role.setAddTime(date);
        role.setUpdateTime(date);
        role.setEnabled(true);
        role.setDeleted(false);

        // 获取插入后的角色id
        Integer id = roleMapper.insert(role);
        role.setId(id);

        // 给roleVO赋值
        RoleOfSystemRoleVO roleVO = new RoleOfSystemRoleVO();
        roleVO.setId(id);
        roleVO.setName(createRoleBO.getName());
        roleVO.setDesc(createRoleBO.getDesc());
        roleVO.setAddTime(date);
        roleVO.setUpdateTime(date);

        return roleVO;
    }

    /**
     * 修改角色信息
     *
     * @param role
     * @return int
     * @author WuHuaguo
     * @since 2022/06/05 16:42
     */
    @Override
    public int roleUpdate(Role role) {
        // 修改更新时间
        Date date = new Date();
        role.setUpdateTime(date);

        try {
            // 更新角色
            roleMapper.updateByPrimaryKey(role);
        } catch (Exception e) {
            // 角色名称已经存在，更新失败
            return CONSTANT.getFailCode3();
        }

        // 更新角色成功
        return CONSTANT.getSuccessCode();
    }

    /**
     * 删除角色
     *
     * @param role
     * @return void
     * @author WuHuaguo
     * @since 2022/06/05 17:10
     */
    @Override
    public void roleDelete(Role role) {
        // 将deleted设置为true
        role.setDeleted(true);

        // 将该角色的deleted修改为true
        roleMapper.updateByPrimaryKey(role);
    }

    /**
     * 获取操作日志列表
     *
     * @param baseParam
     * @return com.cskaoyan.bean.vo.SystemLogListVO
     * @author WuHuaguo
     * @since 2022/06/06 15:45
     */
    @Override
    public SystemLogListVO logList(BaseParam baseParam) {
        // 分页
        PageHelper.startPage(baseParam.getPage(), baseParam.getLimit());

        // 查询
        LogExample example = new LogExample();
        example.setOrderByClause(baseParam.getSort() + " " + baseParam.getOrder());
        List<Log> logList = logMapper.selectByExample(example);

        // 获取分页后的结果
        PageInfo<Log> pageInfo = new PageInfo<>(logList);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();

        SystemLogListVO logListVO = new SystemLogListVO();
        logListVO.setLimit(baseParam.getLimit());
        logListVO.setPage(baseParam.getPage());
        logListVO.setPages(pages);
        logListVO.setTotal((int) total);
        logListVO.setList(logList);

        return logListVO;
    }

    /**
     * 根据admin的username查询
     *
     * @param username
     * @return
     */
    @Override
    public List<Admin> adminLogin(String username) {
        AdminExample adminExample = new AdminExample();
        AdminExample.Criteria criteria = adminExample.createCriteria();
        if (username != null) {
            criteria.andUsernameEqualTo(username);
        }
        criteria.andDeletedEqualTo(false);
        List<Admin> admins = adminMapper.selectByExample(adminExample);
        return admins;
    }

    /**
     * 根据roleId查询对应的权限
     *
     * @param role
     * @return
     */
    @Override
    public List<String> adminPerms(Integer role) {
        return permissionMapper.queryPermsByRoleId(role, false);
    }

    /**
     * 修改admin密码
     *  @param realPassword
     * @param newPassword
     * @param id
     */
    @Override
    public void profilePassword(String realPassword, String newPassword, Integer adminId) {
        adminMapper.updatePasswordByOldPwd(realPassword, newPassword,adminId);
    }

    /**
     * 根据角色id查询角色名
     * @param roleId
     * @return
     */
    @Override
    public String adminRoles(Integer roleId) {
        return roleMapper.queryNameById(roleId);
    }

    @Override
    public String adminPermUrl(String perm) {
        return  permissionUrlMapper.queryUrlByPerm(perm);
    }
}
